﻿using CoachingOrganizer.Database.DataAccess;
using System;
using System.Linq;
using System.Collections.Generic;
using CoachingOrganizer.ClientInfrastructure.ServicesEntities.LocalStorage;
using CoachingOrganizer.Toolkit.Events;

namespace CoachingOrganizer.Database.DataAccessLayer
{
    public class PeriodDAL : IPeriodInfo
    {
        private readonly DbManagerBase _dbManager;
        private readonly List<GoalDAL> _goals = new List<GoalDAL>();
        private PeriodDA _da;
        public DateTime _start = DateTime.Today;
        public DateTime _finish = DateTime.Today.AddDays(7.0);

        public List<GoalDAL> Goals
        {
            get { return _goals; }
        }

        public IEnumerable<IGoalInfo> GoalsInfo
        {
            get { return _goals; }
        }

        public DateTime Start
        {
            get { return _start; }
            set { _start = value; }
        }

        public DateTime Finish
        {
            get { return _finish; }
            set { _finish = value; }
        }

        public PeriodDAL(DbManagerBase dbManager)
        {
            _dbManager = dbManager;
        }

        public PeriodDA CreateNewDA()
        {
            return _da = new PeriodDA
            {
                Start = _start,
                Finish = _finish
            };
        }

        public ActionResult Save()
        {
            _da.Start = _start;
            _da.Finish = _finish;
            return _dbManager.SafeRun(() => _dbManager.Context.InsertOrReplace(_da));
        }

        public bool Load(int id)
        {
            PeriodDA period = _dbManager.Context.Find<PeriodDA>(da => da.Id == id);
            if (period == null)
                return false;
            Load(period);
            return true;
        }

        public void Load(PeriodDA period)
        {
            _da = period;
            _start = period.Start;
            _finish = period.Finish;
            LoadGoals();
        }

        public ActionResult Remove()
        {
            if (_da != null)
                return _dbManager.SafeRun(() => _dbManager.Context.Delete<PeriodDA>(_da.Id));
            return ActionResult.GetErrorResult(new KeyNotFoundException());
        }

        public ActionResult<IGoalInfo> AddNewGoal(Action<IGoalInfo> initCallback)
        {
            GoalDAL newGoal = CreateNewGoal();
            if (initCallback != null)
                initCallback(newGoal);
            ActionResult addResult = AddGoal(newGoal);
            return addResult.IsValid ? ActionResult<IGoalInfo>.GetValidResult(newGoal) : ActionResult<IGoalInfo>.GetErrorResult(addResult);
        }

        public GoalDAL CreateNewGoal()
        {
            return new GoalDAL(_dbManager);
        }

        public ActionResult AddGoal(GoalDAL goal)
        {
            ActionResult outResult = _dbManager.SafeRun(() => _dbManager.Context.Insert(goal.CreateNewDA(_da)));
            if (outResult.IsValid)
                _goals.Add(goal);
            return outResult;
        }

        public ActionResult LoadGoals()
        {
            return _dbManager.SafeRun(() =>
            {
                foreach (GoalDA goalDA in _dbManager.Context.Table<GoalDA>().Where(g => g.PeriodId == _da.Id).ToArray())
                {
                    GoalDAL goal = new GoalDAL(_dbManager);
                    goal.Load(goalDA);
                    _goals.Add(goal);
                }
            });
        }

    }
}

